package com.cayte.location;

import android.annotation.SuppressLint;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;

public class CayteLocationCallback {
	private long interval = 5000, minTime = 5000;
	private Context con;

	private CayteLocationAIDLServic aidlService;
	private OnGetLocation onGetLocation;

	/**
	 * 设置OnGetLocation监听
	 * 
	 * @param onGetLocation
	 */
	public void setOnGetLocation(OnGetLocation onGetLocation) {
		this.onGetLocation = onGetLocation;
	}

	private ServiceConnection aidlConnection = new ServiceConnection() {
		public void onServiceConnected(ComponentName className, IBinder service) {
			aidlService = CayteLocationAIDLServic.Stub.asInterface(service);
			try {
				aidlService.setMinTime(minTime);
				runGetTask();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		public void onServiceDisconnected(ComponentName className) {
			aidlService = null;
		}
	};

	/**
	 * 设置从Service获取Location时间间隔
	 * 
	 * @param interval
	 *            时间间隔
	 */
	public void setInterval(long interval) {
		if (interval < 3000)
			interval = 3000;
		this.interval = interval;
	}

	/**
	 * 设置Service中抓取Location的时间间隔,一般与interval相同,此方法必须在startService前使用
	 * 
	 * @param minTime
	 *            最短时间间隔
	 */
	public void setMinTime(long minTime) {
		if (minTime < 3000)
			minTime = 3000;
		this.minTime = minTime;
		if (aidlService != null) {
			try {
				aidlService.setMinTime(minTime);
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	public CayteLocationCallback(Context con) {
		this.con = con.getApplicationContext();
	}

	/**
	 * 启动Service开始抓取地址
	 * 
	 * @param onGetLocation
	 *            OnGetLocation监听
	 * 
	 */
	public void startService(OnGetLocation onGetLocation) {
		// TODO Auto-generated method stub
		if (onGetLocation != null)
			this.onGetLocation = onGetLocation;
		Bundle args = new Bundle();
		args.putString("packageName", con.getPackageName());
		Intent intent = new Intent(con, CayteLocationService.class);
		intent.putExtras(args);
		this.con.bindService(intent, aidlConnection, Context.BIND_AUTO_CREATE);
		this.con.startService(intent);
	}

	/**
	 * 停止Service
	 */
	public void stopService() {
		// TODO Auto-generated method stub
		cancelGetTask();
		Bundle args = new Bundle();
		Intent intent = new Intent(con, CayteLocationService.class);
		intent.putExtras(args);
		this.con.unbindService(aidlConnection);
		this.con.stopService(intent);
	}

	private void sleep() {
		long sleepTime = interval;
		int count = (int) (interval / 1000);
		for (int i = 0; i < count; i++) {
			if (sleepTime != interval) {
				return;
			}
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	public abstract interface OnGetLocation {
		public void onGet(int state, CayteLocation loc);
	}

	private class GetTask extends AsyncTask<String, String, String> {
		private Handler getHandler;

		public GetTask(Handler getHandler) {
			// TODO Auto-generated constructor stub
			this.getHandler = getHandler;
		}

		@Override
		protected String doInBackground(String... params) {
			// TODO Auto-generated method stub
			while (true) {
				try {
					onProgressUpdate(aidlService.getLocJson());
				} catch (RemoteException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				sleep();
			}
		}

		@Override
		protected void onProgressUpdate(String... values) {
			// TODO Auto-generated method stub
			super.onProgressUpdate(values);
			if (getHandler != null) {
				CayteLocation loc = CayteLocation.fromJson(values[0]);
				if (loc == null)
					return;
				Message msg = getHandler.obtainMessage(7);
				msg.obj = loc;
				msg.arg1 = loc.state;
				getHandler.sendMessage(msg);
			}
		}
	}

	private GetTask getTask = null;
	private Handler getHandler = null;

	@SuppressLint({ "HandlerLeak" })
	private void runGetTask() {
		// TODO Auto-generated method stub
		cancelGetTask();
		getHandler = new Handler() {
			@Override
			public void dispatchMessage(Message msg) {
				// TODO Auto-generated method stub
				super.dispatchMessage(msg);
				if (msg.what == 7) {
					if (onGetLocation != null) {
						if (msg.arg1 == CayteLocationState.SUCCESS)
							onGetLocation.onGet(msg.arg1,
									(CayteLocation) msg.obj);
						else
							onGetLocation.onGet(msg.arg1, null);
					}
				}
			}
		};
		getTask = new GetTask(getHandler);
		getTask.execute();
	}

	private void cancelGetTask() {
		// TODO Auto-generated method stub
		if (getTask != null) {
			getTask.cancel(true);
		}
		getHandler = null;
		getTask = null;
	}
}
